package net.aspw.client.features.module.impl.exploit

import net.aspw.client.event.EventTarget
import net.aspw.client.event.UpdateEvent
import net.aspw.client.features.module.Module
import net.aspw.client.features.module.ModuleCategory
import net.aspw.client.features.module.ModuleInfo
import net.aspw.client.utils.PacketUtils
import net.aspw.client.utils.timer.MSTimer
import net.aspw.client.value.BoolValue
import net.aspw.client.value.IntegerValue
import net.minecraft.item.ItemBow
import net.minecraft.network.play.client.C03PacketPlayer
import net.minecraft.network.play.client.C07PacketPlayerDigging
import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement
import net.minecraft.util.BlockPos
import net.minecraft.util.EnumFacing

@ModuleInfo(name = "QuickExploits", spacedName = "Quick Exploits", category = ModuleCategory.EXPLOIT)
class QuickExploits : Module() {

    private val perfectHorseJump = BoolValue("PerfectHorseJump", true)
    private val regenValue = BoolValue("Regen", false)
    private val regenSpeedValue = IntegerValue("Regen-Speed", 25, 1, 25, "x") { regenValue.get() }
    val fastBowValue = BoolValue("FastBow", false)
    private val fastBowSpeedValue = IntegerValue("FastBow-Speed", 9, 1, 9, "x") { fastBowValue.get() }
    private val fastBowPowerValue = IntegerValue("FastBow-Power", 20, 1, 20, "x") { fastBowValue.get() }
    private val fireReducerValue = BoolValue("FireReducer", false)
    private val fireReducerSpeedValue = IntegerValue("FireReducer-Speed", 9, 1, 9, "x") { fireReducerValue.get() }

    private val fastBowTimer = MSTimer()

    @EventTarget
    fun onUpdate(event: UpdateEvent) {
        if (perfectHorseJump.get()) {
            mc.thePlayer.horseJumpPowerCounter = 9
            mc.thePlayer.horseJumpPower = 1f
        }

        if (regenValue.get()) {
            if (!mc.thePlayer.capabilities.isCreativeMode && mc.thePlayer.foodStats.foodLevel > 18 && mc.thePlayer.isEntityAlive && mc.thePlayer.health < 18) {
                repeat(regenSpeedValue.get()) {
                    mc.netHandler.addToSendQueue(C03PacketPlayer(mc.thePlayer.onGround))
                }
            }
        }

        if (fastBowValue.get()) {
            if (!mc.thePlayer.isUsingItem)
                return

            if (mc.thePlayer.inventory.getCurrentItem() != null && mc.thePlayer.inventory.getCurrentItem().item is ItemBow) {
                mc.netHandler.addToSendQueue(
                    C08PacketPlayerBlockPlacement(
                        BlockPos.ORIGIN,
                        255,
                        mc.thePlayer.currentEquippedItem,
                        0F,
                        0F,
                        0F
                    )
                )

                for (i in 0 until fastBowPowerValue.get())
                    mc.netHandler.addToSendQueue(
                        C03PacketPlayer.C05PacketPlayerLook(
                            mc.thePlayer.rotationYaw,
                            mc.thePlayer.rotationPitch,
                            true
                        )
                    )

                if (fastBowTimer.hasTimePassed(fastBowSpeedValue.get().toLong())) {
                    mc.netHandler.addToSendQueue(
                        C07PacketPlayerDigging(
                            C07PacketPlayerDigging.Action.RELEASE_USE_ITEM,
                            BlockPos.ORIGIN,
                            EnumFacing.DOWN
                        )
                    )
                    fastBowTimer.reset()
                }

                mc.thePlayer.itemInUseCount = mc.thePlayer.inventory.getCurrentItem().maxItemUseDuration - 1
            }
        }

        if (fireReducerValue.get()) {
            if (mc.playerController.gameIsSurvivalOrAdventure() && mc.thePlayer.isBurning) {
                repeat(fireReducerSpeedValue.get()) {
                    PacketUtils.sendPacketNoEvent(C03PacketPlayer(mc.thePlayer.onGround))
                }
            }
        }
    }
}